////////////////////////////////////////////////////////////////////
// Programme de compression/décompression DRP pour Chrono Cross
////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////
// Nemesis pour Terminus Traduction (tt_nemesis@yahoo.fr)
// Date de création :		05/08/03
// Dernière modification :	31/05/04
////////////////////////////////////////////////////////////////////

// Entete
#include "Patcheur.h"

#define DRP_ENTETE			12
#define DRP_DESCR			12

int fichs_nb2;
char entete[DRP_ENTETE];
char entetes[NB_MAX][DRP_DESCR];

/*------------------------------------------------------------------
  Décompression DRP d'un fichier
--------------------------------------------------------------------
 <- fich : fichier DRP à décompresser
------------------------------------------------------------------*/
JNIEXPORT jint JNICALL Java_Librairie_drp_1decompression
  (JNIEnv *env, jclass cl, jstring fichier)
{
	const char *fich = env->GetStringUTFChars(fichier,0);

	// Fichier Drp à décompresser
	FILE *drp_f;
	char drp_nom[FICH_MAX];
	// Fichier de sortie
	FILE *out_f;
	char dir_nom[FICH_MAX];
	char out_nom[FICH_MAX];
	// Adresses des fichiers
	int adresses[NB_MAX];
	// Index des fichiers
	int f;
	// Position d'arrêt de copie
	int pos;
	// Buffer
	char buffer[BUFFER];

	// Ouverture du fichier DRP
	sprintf(drp_nom,"%s\\%s",DIR_BASE,fich);
	drp_f=fopen(drp_nom,"rb");

	// Fichier existant ?
	if (drp_f==NULL)
		return ERROR_ISO;

	// Creation du dossier de sortie
	sprintf(dir_nom,"%s\\%s%s",DIR_BASE,fich,DIR_SUFF);
	if (mkdir(dir_nom)!=0 && errno==ENOENT)
		return ERROR_DIR;

	// Récupération de l'entête
	fread(entete,sizeof(char),DRP_ENTETE,drp_f);
	// Chargement des adresses
	fichs_nb2=-1;

	do {
		fichs_nb2++;
		fread(&adresses[fichs_nb2],sizeof(int),1,drp_f);
	} while(adresses[fichs_nb2]!=0);
	// Modification pour la dernière adresse
	fseek(drp_f,0L,SEEK_END);
	adresses[fichs_nb2]=ftell(drp_f);

	// Décompression des fichiers
	for(f=0;f<fichs_nb2;f++) {
		// Ouverture du fichier extrait
		sprintf(out_nom,"%s\\%04d",dir_nom,f);
		out_f=fopen(out_nom,"wb");
		if (out_f==NULL)
			return ERROR_FILE;
		// Placement au niveau du fichier
		fseek(drp_f,adresses[f],SEEK_SET);

		// Récupération de l'entête de fichier
		fread(entetes[f],sizeof(char),DRP_DESCR,drp_f);
		// Extraction du fichier
		for(pos=adresses[f]+DRP_DESCR;
			pos<=adresses[f+1]-BUFFER;
			pos+=BUFFER)
		{
			fread(buffer,sizeof(char),BUFFER,drp_f);
			fwrite(&buffer,sizeof(char),BUFFER,out_f);
		}
		// Attention à l'ordre pour
		// rester dans les positifs
		pos=(adresses[f+1]-adresses[f]-DRP_DESCR)%BUFFER;
		fread(buffer,sizeof(char),pos,drp_f);
		fwrite(&buffer,sizeof(char),pos,out_f);
		// Fermeture du fichier extrait
		fclose(out_f);
	}
	// Fermeture du DRP
	fclose(drp_f);
	// Suppression du DRP
	remove(drp_nom);

	return ERROR_NONE;
}

/*------------------------------------------------------------------
  Compression DRP de fichiers
--------------------------------------------------------------------
 <- fich : fichier DRP à compresser
 (on suppose que le nombre d'éléments et l'entêtes sont mémorisé
  lors de la décompression => interdiction de Drp_D, Drp_D, Drp_C)
------------------------------------------------------------------*/
JNIEXPORT jint JNICALL Java_Librairie_drp_1compression
  (JNIEnv *env, jclass cl, jstring fichier)
{
	const char *fich = env->GetStringUTFChars(fichier,0);

	// Fichier Drp à décompresser
	FILE *drp_f;
	char drp_nom[FICH_MAX];
	// Fichiers d'entrée
	FILE *in_f;
	char in_nom[FICH_MAX];
	// Adresses des fichiers
	int adresses[NB_MAX];
	// Index des fichiers
	int f;
	// Buffer
	char buffer[BUFFER];
	// Nombre d'octets lus
	int result;

	// Ouverture du fichier DRP
	sprintf(drp_nom,"%s\\%s",DIR_BASE,fich);
	drp_f=fopen(drp_nom,"wb");

	// Fichier créé ?
	if (drp_f==NULL)
		return ERROR_FILE;

	// Changement de dossier
	sprintf(drp_nom,"%s\\%s%s",DIR_BASE,fich,DIR_SUFF);

	// Ecriture du début d'entête de l'original
	fwrite(entete,sizeof(char),DRP_ENTETE,drp_f);

	// Saut au niveau de la fin de l'entête
	fseek(drp_f,fichs_nb2*sizeof(int)+DRP_ENTETE,SEEK_SET);

	// Recompression des fichiers
	for(f=0;f<fichs_nb2;f++) {
		adresses[f]=ftell(drp_f);
		// Ecriture de l'entête de fichier
		fwrite(entetes[f],sizeof(char),DRP_DESCR,drp_f);
		// Completion du fichier source
		sprintf(in_nom,"%s\\%04d",drp_nom,f);
		Fichier_Completer(in_nom);
		// Ouverture du fichier à réinsérer
		in_f=fopen(in_nom,"rb");
		if (in_f==NULL)
			return ERROR_FILE;

		// Copie des données
		while((result=fread(buffer,sizeof(char),BUFFER,in_f))>0)
			fwrite(&buffer,sizeof(char),result,drp_f);
		// Fermeture du fichier extrait
		fclose(in_f);
		// Suppression du fichier
		remove(in_nom);
	}
	// Retour au début
	fseek(drp_f,DRP_ENTETE,SEEK_SET);
	// Ecriture des adresses
	for (f=0;f<fichs_nb2;f++)
		fwrite(&adresses[f],sizeof(int),1,drp_f);
	// Fermeture du fichier
	fclose(drp_f);
	// Suppression du dossier
	rmdir(drp_nom);

	return ERROR_NONE;
}